#ifndef CLIENT_H
#define CLIENT_H

#include <QMainWindow>

namespace Ui {
class Client;
}

class QTcpSocket;
class QUdpSocket;
class QListWidgetItem;
class Chat;

enum udpCommunicationMode{unicast,broadcast};    // UDP 的通信模式

enum udpMsgType{Msg,UserEnter,UserLeft,FileName,Refuse};   // UDP广播消息类型

enum userType{login,logout};  // 用户是登录还是退出

class Client : public QMainWindow
{
    Q_OBJECT

public:
    explicit Client(QWidget *parent = nullptr);
    ~Client();

    bool getValidIP();  // 获取有效IP地址

    void setUserName(const QString&); // 设置用户名       

    void broadcastInfo();   // 通过广播的形式将用户名和IP广播出去    

    bool connectServer();   // 连接服务器，以获取在线用户列表等信息

    void disconnectServer();    // 断开服务器

    void sendLocalInfoToServer();   // 将本机的信息发送到服务器

    void logOut(QString out);

private:
    void initUI();  // 初始化UI界面

    void initAll();    // 初始化数据和绑定槽函数

    // 以指定的通信模式，将指定数据类型的数据报发送到目标网络IP
    void sendMsg(const udpCommunicationMode &mode=unicast,const udpMsgType &msgType=Msg,
                 const QString &targetIP="", const QString &content="");

    void updateOnlineList(const userType &type=login,const QString &username="",const QString &ip="");

    void sendTcpMsg(const QString &msgType,const QString item);  // 告诉服务器用户是上线还是下线，item的内容形式为“username:ip”

private slots:
    void onReadyRead(); // udp中 readyRead信号对应的槽函数

    void onTcpReadyRead();  // tcp中 readyRead信号对应的槽函数

    void onItemDoubleClicked(QListWidgetItem*);

    void on_btnSend_clicked();

    void on_btnSend_2_clicked();

private:
    Ui::Client *ui;

    QTcpSocket *tcpSocket;  // tcp套接字
    QUdpSocket *udpSocket;  // udp套接字

    QString ip; // 有效IP
    QString username;   // 用户名

    QString targetIp;   // 聊天对象IP
    QString targetUsername = "全体成员"; // 聊天对象用户名


    // QWidget interface
protected:
    void closeEvent(QCloseEvent *event);
};

#endif // CLIENT_H
